home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / GRAYPLOT / GRAYPLOT.C1 < prev   
Text File  |  1990-06-13  |  6KB  |  211 lines

  1. /*
  2.  * Grayplot32Bit.c -- display a raw data file using a gray scale ramp palette,
  3.  * restoring the system palette on exit.  This program writes *directly* to the
  4.  * pixmap, so it is much much faster than using SetCPixel().  This program only
  5.  * works with 32Bit QuickDraw!
  6.  * 
  7.  * The format this program expects is a series of bytes, each of which represents
  8.  * a pixel.  An individual byte's  value corresponds to a different shade of gray,
  9.  * ranging from black (for zero) to white (for 255).  For instance, if you have a
  10.  * 256 x 256 pixel file, using any number of colors, it should be 65536 bytes long
  11.  * on disk.
  12.  * 
  13.  * Since this is example code, it contains a bare minimum of the standard error
  14.  * checks and user interface expected of a real program.  It is only intended as a
  15.  * starting point. 
  16.  * Copyright ⌐ 1990 Phil Shapiro, Symantec Corp.
  17.  */
  18. #include <EventMgr.h>
  19. #include <WindowMgr.h>
  20. #include <ColorToolBox.h>
  21. #include <QuickDraw32bit.h>
  22. #include <StdFilePkg.h>
  23. #include <OSUtil.h>
  24.  
  25. #define ScreenDepth(gdh)    ((**((**gdh).gdPMap)).pixelSize)
  26.  
  27. /*
  28.  * Change these numbers to customize this program.
  29.  * COLORS    - the number of shades you want to use to display your data.  This
  30.  *            shouldn't be greater than the number of shades your screen can display.
  31.  * WIDTH    - the width of the data in pixels (discrete data elements)
  32.  * HEIGHT    - the height of the data in pixels (discrete data elements)
  33.  * MAGNIFY    - magnification factor to apply to the display.  The actual
  34.  *            magnification is done by CopyBits().  This value can be a fraction.
  35.  * USE_GRAY    - if you don't want to use a gray scale palette, set this to zero
  36.  *            and the program will use the default system palette.
  37.  * USE_DITHER    - 32 Bit QuickDraw has a built-in dithering mode.  This constant
  38.  *            either selects (any non-zero value) or deselects (zero) this mode.
  39.  */
  40. #define COLORS    16
  41. #define WIDTH    256
  42. #define HEIGHT    256
  43. #define MAGNIFY    1.0
  44. #define USE_GRAY    1
  45. #define USE_DITHER    0
  46.  
  47. unsigned char *Graph;            /* contents of file */
  48.  
  49. #define NIL 0L
  50. #define EXACT    0        /* used with pmTolerant, only exact matches */
  51. /* 32bit quickdraw has a built-in gray ramp, located at
  52.     (32 + <the bit depth of the ramp>). */
  53. #define GRAY_RAMP    32
  54.  
  55. void CheckWorld(void);
  56. void Die(char *pstr);
  57. void Init(void);
  58. void ReadFile(void);
  59. void SetGrayPalette(int depth, CWindowPtr w);
  60. void DrawWindow(Rect bounds);
  61. short log2(unsigned short);
  62. void RestoreClut(GDHandle myGDevice, CWindowPtr w);
  63.  
  64. main()
  65. {
  66.     GDHandle    myGDevice;
  67.     Rect windRect, offBounds = { 0, 0, WIDTH, HEIGHT};
  68.     CWindowPtr    mainWindow;
  69.  
  70.     CheckWorld();
  71.     Init();
  72.     ReadFile();
  73.     myGDevice = GetGDevice();
  74.  
  75.     SetRect(&windRect, 15, 15 + GetMBarHeight(),
  76.             (short)(MAGNIFY * WIDTH), (short)(MAGNIFY * HEIGHT));
  77.     mainWindow = (CWindowPtr)NewCWindow(NIL, &windRect, "\p", TRUE,
  78.                                         dBoxProc, (CWindowPtr)-1, TRUE, 0);
  79.     SetPort(mainWindow);
  80. #if USE_GRAY
  81.     SetGrayPalette(ScreenDepth(myGDevice), mainWindow);
  82. #endif
  83.     DrawWindow(offBounds);
  84.     while (!Button())
  85.         SystemTask();
  86.     DisposeWindow(mainWindow);
  87. #if USE_GRAY
  88.     RestoreDeviceClut(myGDevice);
  89. #endif
  90. }
  91.  
  92. #if USE_GRAY
  93. void SetGrayPalette(int depth, CWindowPtr w)
  94. {
  95.     CTabHandle        tab = GetCTable(GRAY_RAMP + depth);
  96.     PaletteHandle    newPal = NewPalette((**tab).ctSize, tab, pmTolerant, EXACT);
  97.  
  98.     NSetPalette(w, newPal, pmAllUpdates);
  99.     ActivatePalette(w);
  100. }
  101.  
  102. /*
  103.  * integer log base 2 function, to convert colors to bit depth
  104.  */
  105. short log2(unsigned short x)
  106. {
  107.     short t = 0;
  108.  
  109.     while (x >>= 1)
  110.         ++t;
  111.     return t;
  112. }
  113. #endif    /* USE_GRAY */
  114.  
  115. void ReadFile()
  116. {
  117.     OSErr err;
  118.     SFReply reply;
  119.     short refNum;
  120.     long size = (long)sizeof(unsigned char) * WIDTH * HEIGHT;
  121.  
  122.     SFGetFile(0x00400030, "\p", NIL, -1, NIL, NIL, &reply);
  123.     if (reply.good) {
  124.         Graph = (unsigned char *) NewPtr(size);
  125.         if (Graph) {
  126.             if ((err = FSOpen(reply.fName, reply.vRefNum, &refNum)) == noErr) {
  127.                 err = FSRead(refNum, &size, Graph);
  128.                 err = FSClose(refNum);
  129.                 return;
  130.             }
  131.         }
  132.     }
  133.     ExitToShell();        /* User pressed cancel or file i/o messed up. */
  134. }
  135.  
  136. void DrawWindow(Rect bounds)
  137. {
  138.     short i;
  139.     PixMapHandle pm;
  140.     CTabHandle ctab;
  141.     ColorSpec *specs;
  142.  
  143. /*
  144.  * make pixmap from scratch, this should work in future versions...
  145.  */
  146.     pm = (PixMapHandle)NewHandleClear(sizeof(PixMap));
  147.     (**pm).baseAddr = (Ptr)Graph;
  148.     (**pm).rowBytes = (1L << 15) | WIDTH;    /* hi bit means it's a PixMap */
  149.     (**pm).bounds = bounds;
  150.     (**pm).hRes = 72;        /* 72 dpi */
  151.     (**pm).vRes = 72;        /* 72 dpi */
  152.     (**pm).pixelSize = 8;    /* 8 bits per pixel */
  153.     (**pm).cmpCount = 1;    /* 1 pixel per component */
  154.     (**pm).cmpSize = 8;        /* 8 bits per component */
  155. #if USE_GRAY
  156. /*
  157.  * munge a copy of the system color table for my offscreen world
  158.  */
  159.     ctab = GetCTable(log2(COLORS));
  160.     specs = (**ctab).ctTable;
  161.     for (i = 0; i < COLORS; ++i) {
  162.         specs[i].rgb.red = specs[i].rgb.green = specs[i].rgb.blue
  163.             = i * 65535 / (COLORS - 1);
  164.         specs[i].value = i;
  165.     }
  166.     /* this alerts the color mgr that the table changed */
  167.     (**ctab).ctSeed = GetCTSeed();
  168.     (**pm).pmTable = ctab;
  169. #else    /* USE_GRAY */
  170.     (**pm).pmTable = (*((CGrafPtr)thePort)->portPixMap)->pmTable;
  171. #endif    /* USE_GRAY */
  172.     HLock(pm);
  173.     CopyBits(*pm, &thePort->portBits, &(**pm).bounds, &thePort->portRect,
  174.             ( USE_DITHER ? ditherCopy : srcCopy), 0);
  175.     HUnlock(pm);
  176. }
  177.  
  178. void Init()
  179. {
  180.     InitGraf(&thePort);
  181.     InitFonts();
  182.     FlushEvents( everyEvent, 0 );
  183.     InitWindows();
  184.     InitMenus();
  185.     TEInit();
  186.     InitDialogs(0L);
  187.     InitCursor();
  188. }
  189.  
  190. #define QD32Trap    0xAB03
  191. #define    UnImplTrap    0xA89F
  192.  
  193. void CheckWorld()
  194. {
  195.     OSErr        err;
  196.     SysEnvRec    world;
  197.  
  198.     err = SysEnvirons(2, &world);
  199.     if (!world.hasColorQD)
  200.         Die("\pno color qd");
  201.     if (NGetTrapAddress(QD32Trap, ToolTrap) ==
  202.             NGetTrapAddress(UnImplTrap, ToolTrap))
  203.         Die("\pno 32bit qd");
  204. }
  205.  
  206. void Die(char *s)
  207. {
  208.     DebugStr(s);
  209.     ExitToShell();
  210. }
  211.